/**
 * 给定三个数组，A、B、C。令f(i,j,k)=Ai*Bj+Bj*Ck+Ck*Ai
 * 求f的第K大的值
 * 首先将A、B、C降序排列，显然f(0,0,0)是最大的。然后考虑第二大的？
 * 显然在f(1,0,0)/f(0,1,0)/f(0,0,1)之间产生。至于到底是谁，用堆即可
 * 注意要去重
 * 
 * 自定义哈希为 *13313, unordered_set 699ms
 *   gp_hash_table 有一半测试点T了
 * 可能是因为set不需要值类型，而gp需要插入一个pair
 * 自定义哈希改为 splitmix， gp_hash_table 617ms
 *                        unordered_set 变为855ms
 * 
 * gp将值类型从char改为llt，时间变为605ms，内存所用区别不大。评测集应该是64位的。
 * 改为bool类型，时间变为682ms，内存区别不大，略有增加。
 * 
 * 结论，对于gp，尽量使用split哈希，值类型使用64位或者32位整型即可
 */
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

using Real = long double;
using llt = long long;
using vi = vector<int>;
using vll = vector<llt>;
using pii = pair<int, int>;
using i128 = __int128_t;

struct _t{
    int a;
    int b;
    int c;
    llt v;
    _t(int i, int j, int k, llt w):a(i),b(j),c(k),v(w){}
    bool operator < (const _t & rhs) const {
        if(this->v != rhs.v) return this->v < rhs.v;
        if(this->a != rhs.a) return this->a > rhs.a;
        if(this->b != rhs.b) return this->b > rhs.b;
        return this->c > rhs.c;
    }
};

template<> struct std::tr1::hash<_t>{
    static std::size_t splitmix64(std::size_t x){
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);        
    }
    std::size_t operator () (const _t & t) const {
        static const std::size_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(t.a + splitmix64(t.b + splitmix64(t.c + FIXED_RANDOM)));
    }
};

template<> struct std::equal_to<_t>{
    bool operator () (const _t & l, const _t & r) const {
        return l.a == r.a and l.b == r.b and l.c == r.c;
    }
};

int N;
int K;
vll A, B, C;

__gnu_pbds::priority_queue<_t> Q;
__gnu_pbds::gp_hash_table<_t, unsigned char> Flag;

llt f(int i, int j, int k){
    return (llt)A[i] * (0LL + B[j] + C[k]) + (llt)B[j] * C[k];
}

void work(){
    cin >> N >> K;
    A.assign(N, {});
    for(auto & i : A) cin >> i;
    B.assign(N, {});
    for(auto & i : B) cin >> i;    
    C.assign(N, {});
    for(auto & i : C) cin >> i;

    sort(A.begin(), A.end(), greater<int>());
    sort(B.begin(), B.end(), greater<int>());
    sort(C.begin(), C.end(), greater<int>());

    Q.push(_t(0, 0, 0, f(0, 0, 0)));
    Flag.insert({_t(0, 0, 0, f(0, 0, 0)), 0});
    
    for(int i=1;i<K;++i){
        auto h = Q.top(); Q.pop();
        if(h.a + 1 != N){
            _t t{h.a + 1, h.b, h.c, f(h.a + 1, h.b, h.c)};
            auto it = Flag.find(t);
            if(it == Flag.end()){
                Flag.insert({t, 0});Q.push(t);
            } 
            
        } 
        if(h.b + 1 != N){
            _t t{h.a, h.b + 1, h.c, f(h.a, h.b + 1, h.c)};
            auto it = Flag.find(t);
            if(it == Flag.end()){
                Flag.insert({t, 0});Q.push(t);
            } 
        } 
        if(h.c + 1 != N){
            _t t{h.a, h.b, h.c + 1, f(h.a, h.b, h.c + 1)};
            auto it = Flag.find(t);
            if(it == Flag.end()){
                Flag.insert({t, 0});Q.push(t);
            } 
        } 
    }

    cout << Q.top().v << endl;
    return;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);	
    // init();
    int nofkase = 1;
	// cin >> nofkase;
	while(nofkase--) work();
	return 0;
}